Setup

Anteriormente, tuviste que instalar el paquete ggplot2 ejecutando install.packages("ggplot2"). Eso instaló el paquete en tu computadora para que R pueda acceder a él. Para usarlo en nuestra sesión actual, tenemos que cargar el paquete usando la función library().

Si no tienes ggplot2 instalado, puedes ejecutar install.packages("ggplot2") en la consola.

ggplot2 es un paquete poderoso que te permite crear gráficos complejos a partir de datos tabulares (datos en un formato de tabla con filas y columnas). El gg en ggplot2 significa “gramática de gráficos”, y el paquete utiliza un vocabulario consistente para crear gráficos de diversos tipos. Por lo tanto, solo necesitamos realizar pequeños cambios en nuestro código si los datos subyacentes cambian o decidimos hacer un diagrama de caja en lugar de un gráfico de dispersión. Este enfoque te ayuda a crear gráficos de calidad publicable con un ajuste y modificación mínimos.

ggplot2 es parte de la serie de paquetes tidyverse.

Los gráficos ggplot se construyen paso a paso al agregar nuevas capas, lo que permite una gran flexibilidad y personalización de los gráficos.

Para construir un gráfico, utilizaremos una plantilla básica que se puede usar para diferentes tipos de gráficos:

Usamos la función ggplot() para crear un gráfico. Para indicarle qué datos usar, necesitamos especificar el argumento data. Un argumento es una entrada que toma una función, y se establecen argumentos utilizando el signo =.

ggplot(data = surveys_complete)

Obtenemos un gráfico en blanco porque no le hemos indicado a ggplot() qué variables queremos que correspondan a las partes del gráfico. Podemos especificar la “asignación” de variables a los elementos del gráfico, como las coordenadas x/y, tamaño o forma, utilizando la función aes(). También añadiremos un comentario, que es cualquier línea que comienza con un #. Es una buena idea usar comentarios para organizar tu código o aclarar lo que estás haciendo.

# agregando una asignación a los ejes x e y

ggplot(data = surveys_complete, mapping = aes(x = weight, y = hindfoot_length))

Ahora tenemos un gráfico con ejes x e y correspondientes a variables de surveys_complete. Sin embargo, no hemos especificado cómo queremos que se muestren los datos. Hacemos esto utilizando funciones geom_, que especifican el tipo de geometría que deseamos, como puntos, líneas o barras. Podemos agregar una capa geom_point() a nuestro gráfico utilizando el signo +. Indentamos en una nueva línea para que sea más fácil de leer, y debemos terminar la primera línea con el signo +.

ggplot(data = surveys_complete, mapping = aes(x = weight, y = hindfoot_length)) +
  geom_point()
## Warning: Removed 3081 rows containing missing values or values outside the scale range
## (`geom_point()`).

::::::::::::::::::::::::::::: ## Cambiando la estética

Construir gráficos ggplot es a menudo un proceso iterativo, así que continuaremos desarrollando el gráfico de dispersión que acabamos de hacer. Puede que hayas notado que partes de nuestro gráfico de dispersión tienen muchos puntos superpuestos, lo que dificulta ver todos los datos. Podemos ajustar la transparencia de los puntos utilizando el argumento alpha, que toma un valor entre 0 y 1:

ggplot(data = surveys_complete, mapping = aes(x = weight, y = hindfoot_length)) +
  geom_point(alpha = 0.2)

También podemos cambiar el color de los puntos:

ggplot(data = surveys_complete, mapping = aes(x = weight, y = hindfoot_length)) +
  geom_point(alpha = 0.2, color = "blue")

Dos problemas comunes que podrías encontrar al trabajar en R son olvidar un paréntesis de cierre o una comilla de cierre. Veamos qué hace cada uno.

Agregando otra variable

Intentemos colorear nuestros puntos de acuerdo con el tipo de parcela de muestreo (la parcela aquí se refiere al área física donde se muestrearon los roedores y no tiene nada que ver con hacer gráficos). Dado que ahora estamos asignando una variable (plot_type) a un componente del gráfico de ggplot2 (color), necesitamos colocar el argumento dentro de aes():

ggplot(data = surveys_complete, mapping = aes(x = weight, y = hindfoot_length, color = plot_type)) +
  geom_point(alpha = 0.2)

Desafío 1: Modificar gráficos

  1. Intenta modificar el gráfico para que la forma del punto varíe según el sex. Establecerás la forma de la misma manera que estableciste el color.

¿Crees que esta es una buena manera de representar el sex con estos datos?

ggplot(data = surveys_complete, 
       mapping = aes(x = weight, y = hindfoot_length, shape = sex)) +
  geom_point(alpha = 0.2)

  1. Ahora intenta cambiar el gráfico para que el color de los puntos varíe según el year. ¿Notas alguna diferencia en la escala de color en comparación con cambiar el color según el tipo de parcela? ¿Por qué crees que sucedió esto?
ggplot(data = surveys_complete, 
       mapping = aes(x = weight, y = hindfoot_length, color = year)) +
  geom_point(alpha = 0.2)

- Para la Parte 2, la escala de color es diferente en comparación con el uso de color = plot_type porque plot_type y year son diferentes tipos de variables. plot_type es una variable categórica, por lo que ggplot2 usa por defecto una escala de color discreta, mientras que year es una variable numérica, así que ggplot2 utiliza una escala de color continua.

Cambiando escalas

La escala de color discreta predeterminada no siempre es ideal: no es amigable para los espectadores con daltonismo y no se traduce bien a escala de grises. Sin embargo, ggplot2 viene con varias otras escalas de color, incluidas las fantásticas escalas viridis, que están diseñadas para ser amigables con el daltonismo y la escala de grises. Podemos cambiar las escalas agregando funciones scale_ a nuestros gráficos:

ggplot(data = surveys_complete, mapping = aes(x = weight, y = hindfoot_length, color = plot_type)) +
  geom_point(alpha = 0.2) +
  scale_color_viridis_d()

Las escalas no solo se aplican a los colores; cualquier componente del gráfico que coloques dentro de aes() puede ser modificado con funciones scale_. Así como modificamos la escala utilizada para mapear plot_type a color, podemos modificar la forma en que weight se mapea al eje x utilizando la función scale_x_log10():

ggplot(data = surveys_complete, mapping = aes(x = weight, y = hindfoot_length, color = plot_type)) +
  geom_point(alpha = 0.2) +
  scale_x_log10()

Una ventaja de ggplot y del tidyverse en general es que los grupos de funciones que hacen cosas similares tienen nombres similares. Cualquier función que modifique una escala de ggplot comienza con scale_, lo que facilita la búsqueda de la función adecuada.

Boxplot

Intentemos hacer un tipo de gráfico completamente diferente. Comenzaremos con nuestros mismos bloques de construcción básicos utilizando ggplot() y aes().

ggplot(data = surveys_complete, mapping = aes(x = plot_type, y = hindfoot_length))

Esta vez, intentemos hacer un diagrama de caja, que tendrá plot_type en el eje x y hindfoot_length en el eje y. Podemos hacer esto agregando geom_boxplot() a nuestro ggplot():

ggplot(data = surveys_complete, mapping = aes(x = plot_type, y = hindfoot_length)) +
  geom_boxplot()
## Warning: Removed 2733 rows containing non-finite outside the scale range
## (`stat_boxplot()`).

Al igual que coloreamos los puntos antes, también podemos colorear nuestro diagrama de caja según plot_type:

ggplot(data = surveys_complete, mapping = aes(x = plot_type, y = hindfoot_length, color = plot_type)) +
  geom_boxplot()

Parece que color solo ha afectado los contornos del diagrama de caja, no las porciones rectangulares. Esto se debe a que color solo impacta las partes unidimensionales de un ggplot: puntos y líneas. Para cambiar el color de las partes bidimensionales de un gráfico, usamos fill:

ggplot(data = surveys_complete, mapping = aes(x = plot_type, y = hindfoot_length, fill = plot_type)) +
  geom_boxplot()

Una cosa que puedes notar es que las etiquetas de los ejes se superponen entre sí, dependiendo de cuán ancho sea tu visor de gráficos. Una forma de ayudar a que sean más legibles es ajustar el texto. Podemos hacer eso modificando las etiquetas para la escala del eje x.

Usamos la función scale_x_discrete() porque tenemos un eje discreto, y modificamos el argumento labels. La función label_wrap_gen() ajustará el texto de las etiquetas para que sean más legibles.

ggplot(data = surveys_complete, mapping = aes(x = plot_type, y = hindfoot_length, fill = plot_type)) +
  geom_boxplot() +
  scale_x_discrete(labels = label_wrap_gen(width = 10))

Agregando geoms

Uno de los aspectos más poderosos de ggplot es la forma en que podemos agregar componentes a un gráfico en capas sucesivas. Aunque los diagramas de caja pueden ser muy útiles para resumir datos, a menudo es útil mostrar también los datos en bruto. Con ggplot, podemos agregar fácilmente otro geom_ a nuestro gráfico para mostrar los datos en bruto.

Agreguemos geom_point() para visualizar los datos en bruto. Modificaremos el argumento alpha para ayudar a evitar la superposición de puntos.

ggplot(data = surveys_complete, mapping = aes(x = plot_type, y = hindfoot_length)) +
  geom_boxplot() +
  geom_point(alpha = 0.2)

Uh oh… todos nuestros puntos para una categoría dada del eje x caen exactamente en una línea, lo cual no es muy útil. Podemos cambiar a usar geom_jitter(), que añadirá puntos con un poco de ruido aleatorio a las posiciones para prevenir que esto suceda.

ggplot(data = surveys_complete, mapping = aes(x = plot_type, y = hindfoot_length)) +
  geom_boxplot() +
  geom_jitter(alpha = 0.2)

Es posible que hayas notado que algunos de nuestros puntos de datos ahora aparecen en nuestro gráfico dos veces: los valores atípicos se trazan como puntos negros de geom_boxplot(), pero también se trazan con geom_jitter(). Dado que no queremos representar estos datos múltiples veces en la misma forma (puntos), podemos evitar que geom_boxplot() los trace. Hacemos esto configurando el argumento outlier.shape a NA, lo que significa que los valores atípicos no tienen una forma para ser trazados.

ggplot(data = surveys_complete, mapping = aes(x = plot_type, y = hindfoot_length)) +
  geom_boxplot(outlier.shape = NA) +
  geom_jitter(alpha = 0.2)

Al igual que antes, podemos mapear plot_type a color colocándolo dentro de aes().

ggplot(data = surveys_complete, mapping = aes(x = plot_type, y = hindfoot_length, color = plot_type)) +
  geom_boxplot(outlier.shape = NA) +
  geom_jitter(alpha = 0.2)

Notice that both the color of the points and the color of the boxplot lines changed. Any time we specify an aes() mapping inside our initial ggplot() function, that mapping will apply to all our geoms.

If we want to limit the mapping to a single geom, we can put the mapping into the specific geom_ function, like this:

ggplot(data = surveys_complete, mapping = aes(x = plot_type, y = hindfoot_length)) +
  geom_boxplot(outlier.shape = NA) +
  geom_jitter(aes(color = plot_type), alpha = 0.2)

Ahora nuestros puntos están coloreados según plot_type, pero los diagramas de caja son todos del mismo color. Una cosa que podrías notar es que incluso con alpha = 0.2, los puntos oscurecen partes del diagrama de caja. Esto se debe a que la capa geom_point() viene después de la capa geom_boxplot(), lo que significa que los puntos se trazan encima de las cajas. Para poner los diagramas de caja en la parte superior, cambiamos el orden de las capas:

ggplot(data = surveys_complete, mapping = aes(x = plot_type, y = hindfoot_length)) +
  geom_jitter(aes(color = plot_type), alpha = 0.2) +
  geom_boxplot(outlier.shape = NA)

¡Ahora tenemos el problema opuesto! El relleno blanco de los diagramas de caja oscurece completamente algunos de los puntos. Para abordar este problema, podemos eliminar el fill de los diagramas de caja por completo, dejando solo las líneas negras. Para hacer esto, configuramos fill a NA:

ggplot(data = surveys_complete, mapping = aes(x = plot_type, y = hindfoot_length)) +
  geom_jitter(aes(color = plot_type), alpha = 0.2) +
  geom_boxplot(outlier.shape = NA, fill = NA)

Ahora podemos ver todos los datos en bruto y nuestros diagramas de caja en la parte superior.

Desafío 2: Cambiar geoms

Los gráficos de violín son similares a los diagramas de caja; intenta hacer uno usando plot_type y hindfoot_length como las variables en los ejes x e y. Recuerda que todas las funciones geom comienzan con geom_, seguidas del tipo de geom.

Este también podría ser un buen lugar para probar tus habilidades de búsqueda en Internet. A menudo es útil buscar R nombre_del_paquete cosas que deseas buscar. Así que para este ejemplo podríamos buscar R ggplot2 gráfico de violín.

ggplot(data = surveys_complete, 
       mapping = aes(x = plot_type, 
                     y = hindfoot_length,
                     color = plot_type)) +
  geom_jitter(alpha = 0.2) +
  geom_violin(fill = "white")

Para un desafío extra, haz que el color de los puntos y los contornos de los gráficos de violín varíen según plot_type, y establece el relleno de los gráficos de violín en blanco. Intenta jugar con el orden de las capas para ver qué se ve mejor.

ggplot(data = surveys_complete, 
       mapping = aes(x = plot_type, 
                     y = hindfoot_length,
                     color = plot_type)) +
  geom_jitter(alpha = 0.2) +
  geom_violin(fill = "white")

Cambiando temas

Hasta ahora, hemos estado cambiando la apariencia de las partes de nuestro gráfico relacionadas con nuestros datos y las funciones geom_, pero también podemos cambiar muchos de los componentes no relacionados con los datos de nuestro gráfico.

En este punto, estamos bastante contentos con el diseño básico de nuestro gráfico, por lo que podemos asignarlo a un gráfico a un objeto con nombre. Hacemos esto utilizando la flecha de asignación <-. Lo que estamos haciendo aquí es tomar el resultado del código en el lado derecho de la flecha y asignarlo a un objeto cuyo nombre está en el lado izquierdo de la flecha.

Crearemos un objeto llamado myplot. Si ejecutas el nombre del objeto ggplot2, mostrará el gráfico, al igual que si ejecutaras el código por sí mismo.

myplot <- ggplot(data = surveys_complete, mapping = aes(x = plot_type, y = hindfoot_length)) +
  geom_jitter(aes(color = plot_type), alpha = 0.2) +
  geom_boxplot(outlier.shape = NA, fill = NA)

myplot
## Warning: Removed 2733 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
## Warning: Removed 2733 rows containing missing values or values outside the scale range
## (`geom_point()`).

Este proceso de asignar algo a un objeto no es específico de ggplot2, sino que es una característica general de R. Lo utilizaremos mucho en el resto de esta lección. Ahora podemos trabajar con el objeto myplot como si fuera un bloque de código ggplot2, lo que significa que podemos usar + para agregar nuevos componentes a él.

Podemos cambiar la apariencia general utilizando funciones theme_. Intentemos un tema en blanco y negro agregando theme_bw() a nuestro gráfico:

myplot + theme_bw()

Como puedes ver, varias partes del gráfico han cambiado. Las funciones theme_ generalmente controlan muchos aspectos de la apariencia de un gráfico a la vez, por conveniencia. Para cambiar partes individuales de un gráfico, podemos usar la función theme(), que puede aceptar muchos argumentos diferentes para modificar aspectos como el texto, las líneas de la cuadrícula, el color de fondo y más. Intentemos cambiar el tamaño del texto en los títulos de nuestros ejes. Podemos hacer esto especificando que axis.title debe ser un element_text() con el size establecido en 14.

myplot +
  theme_bw() +
  theme(axis.title = element_text(size = 14))

Otro cambio que podríamos querer hacer es eliminar las líneas de la cuadrícula vertical. Dado que nuestro eje x es categórico, esas líneas de la cuadrícula no son útiles. Para hacer esto, dentro de theme(), cambiaremos panel.grid.major.x a element_blank().

myplot +
  theme_bw() +
  theme(axis.title = element_text(size = 14), 
        panel.grid.major.x = element_blank())

Otro cambio útil podría ser eliminar la leyenda de color, ya que esa información ya está en nuestro eje x. Para esto, estableceremos legend.position en “none”.

myplot +
  theme_bw() +
  theme(axis.title = element_text(size = 14), 
        panel.grid.major.x = element_blank(), 
        legend.position = "none")

::::::::::::::::::::::::::::: callout

Debido a que hay tantos posibles argumentos para la función theme(), a veces puede ser difícil encontrar el adecuado. Aquí hay algunos consejos para averiguar cómo modificar un elemento del gráfico:

:::::::::::::::::::::::::::::

Puede que hayas notado que hemos utilizado 3 enfoques diferentes para deshacernos de algo en ggplot:

  • outlier.shape = NA para eliminar los valores atípicos de nuestro boxplot
  • panel.grid.major.x = element_blank() para eliminar las líneas de la cuadrícula x
  • legend.position = "none" para eliminar nuestra leyenda

Cambiando etiquetas

Nuestro gráfico se está formando muy bien ahora. Sin embargo, probablemente queramos hacer que los títulos de los ejes sean más atractivos y, tal vez, agregar un título principal al gráfico. Podemos hacer esto usando la función labs():

myplot +
  theme_bw() +
  theme(axis.title = element_text(size = 14), 
        legend.position = "none") +
  labs(title = "Rodent size by plot type",
       x = "Plot type",
       y = "Hindfoot length (mm)")

Eliminamos nuestra leyenda de este gráfico, pero también puedes cambiar los títulos de varias leyendas usando labs(). Por ejemplo, labs(color = "Tipo de parcela") cambiaría el título de una leyenda de escala de color a “Tipo de parcela”.

Desafío 3: Personalizando un gráfico

Modifica el gráfico anterior añadiendo un subtítulo descriptivo. Aumenta el tamaño de fuente del título del gráfico y hazlo negrita.

Sugerencia: “negrita” se refiere a un “estilo” de fuente.

myplot +
  theme_bw() +
  theme(axis.title = element_text(size = 14), legend.position = "none",
        plot.title = element_text(face = "bold", size = 20)) +
  labs(title = "Rodent size by plot type",
       subtitle = "Long-term dataset from Portal, AZ",
       x = "Plot type",
       y = "Hindfoot length (mm)")

Faceting

Una de las características más poderosas de ggplot es la capacidad de dividir rápidamente un gráfico en múltiples gráficos más pequeños basados en una variable categórica, lo que se llama faceting.

Hasta ahora, hemos mapeado variables en el eje x, el eje y y el color, pero intentar agregar una cuarta variable se vuelve difícil. Cambiar la forma de un punto podría funcionar, pero solo para muy pocas categorías, y aun así, puede ser difícil distinguir las diferencias entre las formas de puntos pequeños.

En lugar de abarrotar una variable más en un solo gráfico, utilizaremos la función facet_wrap() para generar una serie de gráficos más pequeños, divididos por sex. También usamos ncol para especificar que queremos que se dispongan en una sola columna:

myplot +
  theme_bw() +
  theme(axis.title = element_text(size = 14), 
        legend.position = "none", 
        panel.grid.major.x = element_blank()) +
  labs(title = "Rodent size by plot type",
       x = "Plot type",
       y = "Hindfoot length (mm)",
       color = "Plot type") +
  facet_wrap(vars(sex), ncol = 1)

Elfaceting es útil en muchas situaciones. Puede ser beneficioso cuando:

  • una variable categórica tiene demasiados niveles para diferenciarse por color (como un conjunto de datos con 20 países)
  • tus datos se superponen mucho, oscureciendo categorías
  • deseas mostrar más de 3 variables a la vez
  • quieres ver cada categoría en aislamiento, mientras permites comparaciones generales entre categorías

Exportando gráficos

Una vez que estemos satisfechos con nuestro gráfico final, podemos asignar todo a un nuevo objeto, al que podemos llamar finalplot.

finalplot <- myplot +
  theme_bw() +
  theme(axis.title = element_text(size = 14), 
        legend.position = "none", 
        panel.grid.major.x = element_blank()) +
  labs(title = "Rodent size by plot type",
       x = "Plot type",
       y = "Hindfoot length (mm)",
       color = "Plot type") +
  facet_wrap(vars(sex), ncol = 1)

Después de esto, podemos ejecutar ggsave() para guardar nuestro gráfico. El primer argumento que proporcionamos es la ruta al archivo que queremos guardar, incluyendo la extensión correcta del archivo. Este código creará una imagen llamada rodent_size_plots.jpg en el directorio de trabajo de nuestro proyecto actual. Estamos guardando en formato .jpg, pero también puedes guardar en formatos .pdf, .tiff, y otros. A continuación, le indicamos el nombre del objeto gráfico que queremos guardar. También podemos especificar cosas como el ancho y la altura del gráfico en pulgadas.

ggsave(filename = "rodent_size_plots.jpg", plot = finalplot,
       height = 6, width = 8)

Desafío 4: ¡Crea tu propio gráfico!

¡Intenta hacer tu propio gráfico! Puedes ejecutar str(surveys_complete) o ?surveys_complete para explorar las variables que podrías usar en tu nuevo gráfico. Siéntete libre de usar variables que ya hemos visto o algunas que no hemos explorado aún.

Aquí hay un par de ideas para ayudarte a comenzar: